// -----------------------------------------------------------------------
//  <copyright file="FunctionAuthSetUserRoleCommand.cs" company="LiuliuSoft">
//      Copyright (c) 2022-2025 DaprPlus. All rights reserved.
//  </copyright>
//  <site>https://dapr.plus</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2025-01-27 10:00</last-date>
// -----------------------------------------------------------------------

using DaprPlus.Identity.Domain.Entities;
using DaprPlus.Identity.Application.Identity.Users.Dtos;

using Microsoft.AspNetCore.Identity;

namespace DaprPlus.Identity.Application.Identity.Users.Commands;

/// <summary>
/// 功能权限变更时设置用户角色命令
/// </summary>
public class FunctionAuthSetUserRoleCommand : IRequest<ApiResult>, ICommand
{
    public long UserId { get; set; }
    public long FunctionId { get; set; }
    public string FunctionName { get; set; } = null!;
    public bool IsAdd { get; set; }
    public DateTime? BeginTime { get; set; }
    public DateTime? EndTime { get; set; }
}

public class FunctionAuthSetUserRoleCommandHandler(IServiceProvider provider) : IRequestHandler<FunctionAuthSetUserRoleCommand, ApiResult>
{
    public async Task<ApiResult> Handle(FunctionAuthSetUserRoleCommand request, CancellationToken cancellationToken)
    {
        var userManager = provider.GetRequiredService<UserManager<User>>();

        // 查找用户
        var repository = provider.GetRepository<User>();
        var userSpec = new UserByIdSpec<User>(request.UserId).And(new UserIncludeRoleSpec<User>());
        var user = await repository.GetAsync(userSpec, cancellationToken);
        if (user == null)
        {
            return new ApiResult(ApiResultType.Error, $"用户Id为 {request.UserId} 的用户不存在");
        }

        if (user.IsSystem)
        {
            return new ApiResult(ApiResultType.Error, "系统用户不能更改角色分配");
        }

        // 根据功能名称获取对应的角色名称
        var roleName = request.FunctionName.Contains("升级包") ? "升级包" : "全功能";
        var roleNameResolver = provider.GetRequiredService<IRoleNameResolver>();
        var roleId = (await roleNameResolver.ResolveRoleIds([roleName])).FirstOrDefault();
        if (roleId == 0)
        {
            return ApiResult.Error($"名为【{roleName}】的角色不存在");
        }

        var userRole = user.UserRoles.FirstOrDefault(m => m.RoleId == roleId);
        if (userRole == null)
        {
            var result = await userManager.AddToRoleWithTimeAsync(user, roleName, request.BeginTime, request.EndTime,
                cancellationToken);
            await repository.DbContext.SaveChangesAsync(cancellationToken);
            return result.ToApiResult();
        }

        if (request.EndTime.HasValue)
        {
            // 延长角色时间
            if (request.EndTime > userRole.EndTime)
            {
                var result = await userManager.UpdateRoleTimeAsync(user, roleName, request.BeginTime, request.EndTime,
                    cancellationToken);
                await repository.DbContext.SaveChangesAsync(cancellationToken);
                return result.ToApiResult();
            }

            // 删除过期角色
            if (request.EndTime <= DateTime.Now)
            {
                var result = await userManager.RemoveFromRoleAsync(user, roleName);
                await repository.DbContext.SaveChangesAsync(cancellationToken);
                return result.ToApiResult();
            }
        }

        return ApiResult.Success();
    }

}

public class FunctionAuthSetUserRoleCommandValidator : AbstractValidator<FunctionAuthSetUserRoleCommand>
{
    public FunctionAuthSetUserRoleCommandValidator()
    {
        RuleFor(x => x.UserId).GreaterThan(0).WithMessage("用户Id必须大于0");
        RuleFor(x => x.FunctionName).NotEmpty().WithMessage("功能名称不能为空");
        RuleFor(x => x.FunctionId).GreaterThan(0).WithMessage("功能Id必须大于0");
    }
}
